//-----------------------------------------------------------------------
// <copyright file="BackgroundHandler.cs" company="iron9light">
//      Copyright (c) iron9light. All rights reserved.
// </copyright>
// <author>iron9light</author>
//-----------------------------------------------------------------------

namespace EventBroker.Handlers
{
    using System;
    using System.Threading;

    /// <summary>
    /// Handler that executes the subscription on a thread pool worker process (asynchronous).
    /// </summary>
    public class BackgroundHandler : DefaultHandler
    {
        public override void Handle(object sender, EventArgs e, System.Collections.Generic.ICollection<Exception> exceptions)
        {
            ThreadPool.QueueUserWorkItem(
                    delegate(object state)
                    {
                        CallInBackgroundArguments args = (CallInBackgroundArguments)state;

                        args.Handler.DynamicInvoke(args.Sender, args.EventArgs);
                    },
                    new CallInBackgroundArguments(sender, e, this.SubscriptionHandler));
        }

        /// <summary>
        /// Struct that is passed to the background worker thread.
        /// </summary>
        private struct CallInBackgroundArguments
        {
            /// <summary>
            /// The event topic handler method on the subscriber.
            /// </summary>
            public readonly Delegate Handler;

            /// <summary>
            /// The publisher sending the event.
            /// </summary>
            public readonly object Sender;

            /// <summary>
            /// The event args of the event.
            /// </summary>
            public readonly EventArgs EventArgs;

            /// <summary>
            /// Initializes a new instance of the <see cref="CallInBackgroundArguments"/> struct.
            /// </summary>
            /// <param name="sender">The sender.</param>
            /// <param name="eventArgs">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            /// <param name="handler">The handler.</param>
            public CallInBackgroundArguments(object sender, EventArgs eventArgs, Delegate handler)
            {
                this.Sender = sender;
                this.EventArgs = eventArgs;
                this.Handler = handler;
            }
        }
    }
}